package cn.kgc.spring04.jdkproxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * @Author: 课工场
 * @Version: v1.0  2023/4/28
 * @Description:  基于jdk的动态代理
 * 连接点：  可以织入功能增强位置    位置
 * 切点：    本质就是方法  给哪个方法织入功能的增强
 * 通知：    需要增强的业务功能
 *      1.前置通知
 *      2.后置通知
 *      3.最终通知
 *      4.异常通知
 *      5.环绕通知
 * 切面：切点+通知
 */

public class MyJDKProxy {

    private Object target;

    public MyJDKProxy(Object object){
            this.target = object;
    }


    // 获取代理对象的方法
    public  Object  getProxy(){

        /*
        * ClassLoader loader        类加载器  jvm虚拟机不会为动态生成的类分配加载器
          Class<?>[] interfaces     被代理对象实现的接口    target
          InvocationHandler h      增强业务功能的对象
        * */

        ClassLoader classLoader = MyJDKProxy.class.getClassLoader();
        Class<?> clazz = target.getClass();
        Class<?>[] interfaces = clazz.getInterfaces();

        InvocationHandler  invocationHandler = new InvocationHandler() {
            // proxy  代理对象    method  代理对象调用的方法   args  代理对象调用方法的参数 
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {


                Object invoke = null;  //  目标方法的执行
                try {
                    // 前置通知
                    System.out.println("------------上课时间到了--------------");   // 连接点
                    invoke = method.invoke(target, args);    //切点
                    //后置通知
                    System.out.println("------------下课时间到了--------------");    // 连接点
                } catch (Exception e) {
                    e.printStackTrace();
                    // 异常通知
                } finally {
                    // 最终通知
                }

                return invoke;
            }
        };

        Object o = Proxy.newProxyInstance(classLoader, interfaces, invocationHandler);
        return o;
    }


}
